package com.t.bricks.bussiness.service.lucene.impl;

import java.io.File;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.t.bricks.bussiness.component.lucene.LuceneAspectBase;
import com.t.bricks.bussiness.service.lucene.LuceneCoreService;
import com.t.bricks.bussiness.util.lucene.LuceneFactory;
import com.t.bricks.model.Log;
import com.t.bricks.model.MsgEmity;
import com.t.bricks.model.OrderInfoList;
import com.t.bricks.model.Page;
import com.t.bricks.utils.function.file.FileUtil;
import com.t.bricks.utils.function.reflect.ReflectUtil;
import com.t.bricks.utils.spring.SpringContextUtil;

@Service
public class LuceneCoreServiceImpl implements LuceneCoreService {
	
	/**
	 * 搜索引擎文件主路径
	 */
	private static String lucenePath = String.format("%s/temp/lucene/", System.getProperty("user.dir").replaceAll("\\\\", "/"));

	/**
	 * 搜索引擎库根路径配置
	 */
	@Value("${app.lucene.index.path.root:配置文件中的搜索引擎根路径app.lucene.path.root未设置}")
	private String sLuceneIndexPath;

	/**
	 * 查询数据
	 * @param field
	 * @param key
	 * @param sortMap 排序信息集合 [{"字段名1", 是否降序},{"字段名2", 是否降序}]
	 * @param page
	 * @param coreName 库名,默认要求跟表名一致
	 * @return
	 */
	public MsgEmity search(String field, String key, Map<String, Boolean> sortMap,
			Page page, String coreName) {
		if (null == coreName || "".equals(coreName.trim())) {
			return MsgEmity.err(8000, "库名不能为空！");
		}

		if ("配置文件中的搜索引擎根路径app.lucene.path.root未设置".equals(sLuceneIndexPath.trim())) {
			sLuceneIndexPath = String.format("%sindex/", lucenePath);
		}
		
		String core = String.format("%s%s", sLuceneIndexPath, coreName.trim());
		
		return LuceneFactory.search(field, key, sortMap, page, Map.class, core);
	}

	/**
	 * 删除索引库
	 * @param coreName 库名,默认要求跟表名一致
	 * @return
	 */
	public MsgEmity del(String coreName) {
		if (null == coreName || "".equals(coreName.trim())) {
			return MsgEmity.err(8000, "库名不能为空！");
		}

		if ("配置文件中的搜索引擎根路径app.lucene.path.root未设置".equals(sLuceneIndexPath.trim())) {
			sLuceneIndexPath = new StringBuilder(lucenePath).append("index/").toString();
		}
		
		String core = String.format("%s%s", sLuceneIndexPath, coreName.trim());
		
		File file = new File(core);
		if (!file.exists()) {
			return MsgEmity.success(8999, "库本身不存在");
		}
		
		if (!FileUtil.delDir(file) ) {
			return MsgEmity.err(8001, "删除索引库'", core, "'失败！");
		}
		
		Log.debug("索引库'", core, "'删除成功！");
		
		return MsgEmity.success(8999, "删除索引库'", core, "'成功！");
	}

	/**
	 * 重建索引库
	 * @param coreName 库名,默认要求跟表名一致
	 * @return
	 */
	public MsgEmity rebuild(String coreName) {
		if (null == coreName || "".equals(coreName.trim())) {
			return MsgEmity.err(8000, "库名不能为空！");
		}

		if ("配置文件中的搜索引擎根路径app.lucene.path.root未设置".equals(sLuceneIndexPath.trim())) {
			sLuceneIndexPath = new StringBuilder(lucenePath).append("index/").toString();
		}
		
		String core = String.format("%s%s", sLuceneIndexPath, coreName);
		
		File file = new File(core);
		if (file.exists()) {
			if (!FileUtil.delDir(file) ) {
				return MsgEmity.err(8001, "删除索引库'", core, "'失败！");
			}
			
			Log.debug("索引库'", core, "'在重建时删除成功！");
		}

		MsgEmity me = crateLuceneCore(core);//建立搜索库
		if (!me.isSuccess()) {
			return me;
		}
		
		return MsgEmity.success(8999, "删除索引库'", core, "'成功！");
	}
	
	/**
	 * 建立搜索库
	 * @param coreName 库名,默认要求跟表名一致
	 * @return
	 */
	private MsgEmity crateLuceneCore(String coreName) {
		String core = getCore(coreName);
		File file = new File(core);
		if (file.exists()) {
			return MsgEmity.success(6999, "'", core, "'库原本存在!");
		}
		
		synchronized(LuceneAspectBase.class) {
			file = new File(core);
			if (file.exists()) {
				return MsgEmity.success(6999, "'", core, "'库已经存在!");
			}
		
			MsgEmity me = SpringContextUtil.doMethod(
					getDaoBeanName(coreName), "findBySearch",
					new Class<?>[]{ String.class, OrderInfoList.class },
					new Object[]{ " 2=2 ", null });
			if (!me.isSuccess()) {
				Log.error("搜索引擎读取数据失败!");
				return MsgEmity.err(6001, "建'", core, "'库失败!");
			}
			
			me = me.getData();//SpringContextUtil.doMethod返回的data里面是MsgEmity
			if (!me.isSuccess()) {
				return me;
			}
			
			List<?> list = me.getData();
			if (list.size() < 1) {
				return MsgEmity.err(6002, "没有数据，建'", core, "'库失败!");
			}
			
			String idName = "sId";
			if (!ReflectUtil.hasAttr(list.get(0), "sId", true)) {//判定主键
				idName = ReflectUtil.hasAttr(list.get(0), "sId", true) ? "sId" : "iId";
			}
			
			me = LuceneFactory.add(idName, list, core);
			if (!me.isSuccess()) {
				return me;
			}
		}
		
		return MsgEmity.success(6999, "建'", core, "'库成功!");
	}
	
	/**
	 * 取处理事件的Dao实现类名称
	 * @param coreName 库名,默认要求跟表名一致
	 * @return
	 */
	private String getDaoBeanName(String coreName) {
		String beanName = coreName;

		if (beanName == null || beanName.length() == 0) {
			return beanName;
		}
		
		if (beanName.length() > 1
				&& Character.isUpperCase(beanName.charAt(1))
				&& Character.isUpperCase(beanName.charAt(0))) {
			return beanName;//根据springmvc命名规则,如果两个或以上的大写字母开头则直接返回
		}
		
		char chars[] = beanName.toCharArray();
		chars[0] = Character.toLowerCase(chars[0]);
		
		return new String(chars);
	}
	
	/**
	 * 获取库文件地址
	 * @param coreName 库名,默认要求跟表名一致
	 * @return
	 */
	private String getCore(String coreName) {
		if ("配置文件中的搜索引擎根路径app.lucene.path.root未设置".equals(sLuceneIndexPath.trim())) {
			sLuceneIndexPath = String.format("%sindex/", lucenePath);
		}
		
		return String.format("%s%s", sLuceneIndexPath, coreName);
	}
	
}
